<template>
	<div :class="['home-container', homeData.design ? 'design' : '']">
		<div class="home-content">
			<div class="home-top">
				<div class="home-top-title">工作台</div>
				<div class="home-top-actions">
					<el-button v-if="homeData.design" type="primary" icon="ele-Check" round
						@click="save">编辑完成</el-button>
					<el-button v-else type="primary" icon="ele-Edit" round @click="custom">页面装修</el-button>
				</div>
			</div>
			<div class="decoration" ref="decoration" :style="{ transform: decorationTransform }">
				<div class="decoration-wrapper">
					<div v-if="nowCompsList.length <= 0" class="no-decoration">
						<el-empty description="页面为空" :image-size="280"></el-empty>
					</div>
					<el-row :gutter="15">
						<el-col v-for="(item, index) in homeData.grid.layout" v-bind:key="index" :md="item" :sm="12"
							:xs="24">
							<draggable v-model="homeData.grid.copmsList[index]" animation="200" handle=".design-overlay"
								group="people" item-key="com" force-fallback fallbackOnBody class="draggable-box">
								<template #item="{ element }">
									<div class="decoration-item">
										<component v-if="homeData.data" :is="homeData.allComps[element].component" :data="homeData.data"></component>
										<div v-if="homeData.design" class="design-overlay">
											<el-button class="close" type="danger" circle size="small"
												@click="remove(element)">
												<SvgIcon name="ele-Close" size="16" />
											</el-button>
											<label>{{ homeData.allComps[element].info.title }}</label>
										</div>
									</div>
								</template>
							</draggable>
						</el-col>
					</el-row>
				</div>
			</div>
		</div>
		<div v-if="homeData.design" class="home-aside">
			<div class="aside-header">
				<div class="title">
					<span class="flex-1">添加组件</span>
					<div class="close" @click="close()">
						<SvgIcon name="ele-Close" size="16" />
					</div>
				</div>
			</div>
			<div class="aside-style-header">
				<div class="pageLayout">
					<div class="pageLayout-item item01"
						:class="{ active: homeData.grid.layout.join(',') == '6,6,6,6,24,12,12' }"
						@click="setLayout([6, 6, 6, 6, 24, 12, 12])">
						<el-row :gutter="2">
							<el-col :span="6"><span class="!h-[14px] mb-[2px]"></span></el-col>
							<el-col :span="6"><span class="!h-[14px] mb-[2px]"></span></el-col>
							<el-col :span="6"><span class="!h-[14px] mb-[2px]"></span></el-col>
							<el-col :span="6"><span class="!h-[14px] mb-[2px]"></span></el-col>
							<el-col :span="24"><span class="!h-[14px] mb-[2px]"></span></el-col>
							<el-col :span="12"><span class="!h-[14px]"></span></el-col>
							<el-col :span="12"><span class="!h-[14px]"></span></el-col>
						</el-row>
					</div>
					<div class="pageLayout-item item02"
						:class="{ active: homeData.grid.layout.join(',') == '12,12,8,8,8,16,8' }"
						@click="setLayout([12, 12, 8, 8, 8, 16, 8])">
						<el-row :gutter="2">
							<el-col :span="12"><span class="!h-[14px] mb-[2px]"></span></el-col>
							<el-col :span="12"><span class="!h-[14px] mb-[2px]"></span></el-col>
							<el-col :span="8"><span class="!h-[14px] mb-[2px]"></span></el-col>
							<el-col :span="8"><span class="!h-[14px] mb-[2px]"></span></el-col>
							<el-col :span="8"><span class="!h-[14px] mb-[2px]"></span></el-col>
							<el-col :span="16"><span class="!h-[14px]"></span></el-col>
							<el-col :span="8"><span class="!h-[14px]"></span></el-col>
						</el-row>
					</div>
					<div class="pageLayout-item item03"
						:class="{ active: homeData.grid.layout.join(',') == '24,16,8,8,16' }"
						@click="setLayout([24, 16, 8, 8, 16])">
						<el-row :gutter="2">
							<el-col :span="24"><span class="!h-[14px] mb-[2px]"></span></el-col>
							<el-col :span="16"><span class="!h-[14px] mb-[2px]"></span></el-col>
							<el-col :span="8"><span class="!h-[14px] mb-[2px]"></span></el-col>
							<el-col :span="8"><span class="!h-[14px]"></span></el-col>
							<el-col :span="16"><span class="!h-[14px]"></span></el-col>
						</el-row>
					</div>
				</div>
			</div>
			<div class="aside-content">
				<div class="component-list">
					<div v-if="myCompsList.length <= 0" class="component-list-nodata">
						<el-empty description="组件为空" :image-size="60"></el-empty>
					</div>
					<div v-for="item in myCompsList" :key="item.title" class="component-list-item">
						<div class="item-info">
							<h2>{{ item.title }}</h2>
							<p>{{ item.description }}</p>
						</div>
						<div class="item-actions">
							<el-button type="primary" circle size="small" @click="push(item)">
								<SvgIcon name="ele-Plus" class="!mr-0" size="16" />
							</el-button>
						</div>
					</div>
				</div>
			</div>
			<div class="flex justify-center align-middle h-[200px]">
				<el-button size="default" @click="backDefaul()">恢复默认</el-button>
			</div>
		</div>
	</div>
</template>

<script setup lang="ts" name="home">
import { reactive, onMounted, ref, computed, nextTick, watch } from 'vue';
import draggable from 'vuedraggable';
import { Session } from '/@/utils/storage';
import allPageComps from './components';
import { workbenchIndex } from '/@/api/workbench';

const decoration = ref(null);

const homeData = reactive({
	design: false,
	allComps: allPageComps,
	pageLayout: [],
	defaultGrid: {
		layout: [6, 6, 6, 6, 24, 12, 12],
		copmsList: [['articleNumber'], ['articleView'], ['todayUser'], ['userNumber'], ['shortcut'], ['userChart'], ['articleRank']],
	},
	grid: {
		layout: [6, 6, 6, 6, 24, 12, 12],
		copmsList: [],
	} as any,
	data: null
});

const decorationTransform = ref('none');

const getData = async () => {
	const res = await workbenchIndex();
	homeData.data = res;
};

const myCompsList = ref([]);

const getMyCompsList = () => {
	let allCompsPageList = [];

	for (let key in homeData.allComps) {
		allCompsPageList.push({
			key: key,
			title: homeData.allComps[key].info.title,
			description: homeData.allComps[key].info.description,
		});
	}

	let setCompsList = homeData.grid.copmsList.reduce(function (a, b) {
		return a.concat(b);
	});

	for (let comp of allCompsPageList) {
		const _item = setCompsList.find((item) => {
			return item === comp.key;
		});
		if (_item) {
			comp.disabled = true;
		}
	}

	return allCompsPageList.filter((item) => !item.disabled);
}

// 监听布局变化
watch(
	() => homeData.grid.copmsList,
	() => {
		myCompsList.value = getMyCompsList();
},{deep:true})

const nowCompsList = computed(() => {
	return homeData.grid.copmsList.reduce(function (a, b) {
		return a.concat(b);
	});
});

// 开启自定义
const custom = () => {
	homeData.design = true;
	const oldWidth = decoration.value.offsetWidth;
	nextTick(() => {
		decorationTransform.value = `scale(${decoration.value.offsetWidth / oldWidth})`;
	});
};

// 设置布局
const setLayout = (layout) => {
	homeData.grid.layout = layout;
	if (layout.join(',') == '24') {
		homeData.grid.copmsList[0] = [...homeData.grid.copmsList[0], ...homeData.grid.copmsList[1], ...homeData.grid.copmsList[2]];
		homeData.grid.copmsList[1] = [];
		homeData.grid.copmsList[2] = [];
	}
};

// 追加
const push = (item) => {
	let target = homeData.grid.copmsList[0];
	target.push(item.key);
};

// 隐藏组件
const remove = (item) => {
	let newCopmsList = homeData.grid.copmsList;
	newCopmsList.forEach((obj, index) => {
		let newObj = obj.filter((o) => o != item);
		newCopmsList[index] = newObj;
	});
};

// 保存
const save = () => {
	homeData.design = false;
	decorationTransform.value = 'none';
	Session.set('homeGrid', homeData.grid);
};

// 恢复默认
const backDefaul = () => {
	homeData.design = false;
	decorationTransform.value = 'none';
	homeData.grid = JSON.parse(JSON.stringify(homeData.defaultGrid));
	Session.remove('homeGrid');
};

// 关闭
const close = () => {
	homeData.design = false;
	decorationTransform.value = 'none';
};

homeData.grid = Session.get('homeGrid') || JSON.parse(JSON.stringify(homeData.defaultGrid));

onMounted(() => {
	getData();
});
</script>

<style scoped lang="scss">
.home-container {
	display: flex;
	flex-direction: row;
	flex: 1;
	height: 100%;

	.home-content {
		flex: 1;
		overflow: auto;
		overflow-x: hidden;
	}

	.home-top {
		margin-bottom: 15px;
		display: flex;
		justify-content: space-between;
		align-items: center;
		background-color: white;
		padding: 15px;

		.home-top-title {
			font-size: 20px;
		}

		.home-top-actions {
			display: flex;
			align-items: center;
		}
	}

	.decoration {
		transform-origin: top left;
		transition: transform 0.15s;

		.decoration-wrapper .sortable-ghost {
			opacity: 0.5;
		}

		.decoration-item {
			margin-bottom: 15px;
		}
	}

	.home-aside {
		width: 360px;
		background: #fff;
		box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
		position: relative;
		overflow: auto;
		margin-left: 15px;

		.aside-header {
			height: 64px;
			background: #ffffff;
			border-bottom: 1px solid #dde2eb;
			padding: 20px;
			box-sizing: border-box;
			font-weight: 500;
			font-size: 14px;
			line-height: 24px;

			.title {
				font-size: 16px;
				display: flex;
				align-items: center;
				justify-content: center;
			}

			.close {
				font-size: 18px;
				width: 24px;
				height: 24px;
				display: flex;
				align-items: center;
				justify-content: center;
				border-radius: 3px;
				cursor: pointer;
			}

			.close:hover {
				color: var(--el-color-primary);
			}
		}

		.aside-style-header {
			padding: 20px;
		}

		.aside-content {
			padding: 20px;
		}
	}

	.draggable-box {
		height: 100%;
	}

	.design-overlay {
		position: absolute;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		z-index: 1000;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		background: rgba(255, 255, 255, 0.9);
		cursor: move;

		label {
			background: var(--el-color-primary);
			color: #fff;
			height: 46px;
			padding: 0 30px;
			border-radius: 40px;
			font-size: 20px;
			display: flex;
			align-items: center;
			justify-content: center;
			cursor: move;

			i {
				margin-right: 15px;
				font-size: 24px;
			}
		}

		.close {
			position: absolute;
			top: 2px;
			right: 2px;
		}
	}
}

.design {
	.decoration-wrapper {
		margin-right: -374px;

		.el-col {
			padding-bottom: 15px;
		}

		.draggable-box {
			border: 1px dashed var(--el-color-primary);
			padding: 15px;
		}

		.no-decoration {
			display: none;
		}
	}

	.decoration-item {
		position: relative;
		margin-bottom: 15px;
	}

	.decoration-item:last-child {
		margin-bottom: 0;
	}
}

.component-list {
	.component-list-item {
		display: flex;
		flex-direction: row;
		padding: 15px;
		align-items: center;
		border: 1px solid #dde2eb;
		margin-bottom: 5px;

		.item-info {
			flex: 1;

			h2 {
				font-size: 16px;
				font-weight: normal;
				cursor: default;
			}

			p {
				font-size: 12px;
				color: #999;
				cursor: default;
			}
		}
	}

	.component-list-item:hover {
		background: rgba(180, 180, 180, 0.1);
	}
}

.pageLayout {
	width: 100%;
	display: flex;

	.pageLayout-item {
		width: 60px;
		height: 60px;
		border: 2px solid var(--el-border-color-light);
		padding: 5px;
		cursor: pointer;
		margin-right: 15px;

		span {
			display: block;
			background: var(--el-border-color-light);
			height: 46px;
		}
	}

	.pageLayout-item:hover {
		border-color: var(--el-color-primary);
	}

	.pageLayout-item.active {
		border-color: var(--el-color-primary);
	}

	.pageLayout-item.active span {
		background: var(--el-color-primary);
	}
}

@media (max-width: 992px) {
	.design .decoration {
		transform: scale(1) !important;
	}

	.design .home-aside {
		width: 100%;
		position: absolute;
		top: 50%;
		right: 0;
		bottom: 0;
	}

	.design .decoration-wrapper {
		margin-right: 0;
	}
}
</style>
